﻿#region Copyright

// All Material Copyright © 2010 Dynamic Concepts Development Corp., All Rights Reserved.
//      Portions Copyright © 1984-2009 Dynamic Concepts Development Corp., All Rights Reserved.
// For further information please contact: SoftwareSupport@dynconcepts.com
// Dynamic Concepts Development Corp.  311 W 57th St. Suite #422, New York, NY 10019

#endregion

#region Using References

using System;
using System.Collections.Generic;

#endregion

namespace DynConDevCorp.OpenArch.SupportLibrary.ParallelExecution.Scheduling
{
    public class ScheduledExecutionQueue
    {
        #region Public Properies and Indexers

        public TimeSpan TimeTillNextItem
        {
            get
            {
                lock (r_SyncRoot)
                {
                    if (r_QueuedItems.Count == 0) return TimeSpan.MaxValue;
                    return PeekNextItem.NextExecutionTime - DateTime.UtcNow;
                }
            }
        }

        #endregion

        #region Public Methods

        public ScheduledExecutionItem Dequeue()
        {
            lock (r_SyncRoot)
            {
                if (r_QueuedItems.Count == 0) return null;
                ScheduledExecutionItem nextItem = PeekNextItem;
                r_QueuedItems.Remove(nextItem.NextExecutionTime);
                return nextItem;
            }
        }

        public void Enqueue(ScheduledExecutionItem item)
        {
            lock (r_SyncRoot)
            {
                while (r_QueuedItems.ContainsKey(item.NextExecutionTime))
                {
                    item.NextExecutionTime = item.NextExecutionTime.AddTicks(1);
                }
                r_QueuedItems.Add(item.NextExecutionTime, item);
            }
        }

        #endregion

        #region Private Properies and Indexers

        private ScheduledExecutionItem PeekNextItem
        {
            get
            {
                lock (r_SyncRoot)
                {
                    if (r_QueuedItems.Count == 0)
                        return null;
                    return r_QueuedItems.Values[0];
                }
            }
        }

        #endregion

        #region Instance Fields (ReadOnly)

        private readonly SortedList<DateTime, ScheduledExecutionItem> r_QueuedItems = new SortedList<DateTime, ScheduledExecutionItem>();
        private readonly Object r_SyncRoot = new object();

        #endregion
    }
}